package com.ocom.payhandle.mq.business.saveorder;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ocom.common.AcpService;
import com.ocom.common.entity.card.*;
import com.ocom.common.entity.company.EntityCompanyConfig;
import com.ocom.common.entity.pay.EntityAbnormal;
import com.ocom.common.request.payconfig.mealorder.RefundOrderDishesRequest;
import com.ocom.common.request.simple.GzhMsgRequest;
import com.ocom.common.resp.Result;
import com.ocom.common.utils.CommonUtil;
import com.ocom.common.utils.DateUtil;
import com.ocom.common.vo.pay.ServiceChargesVo;
import com.ocom.payhandle.feign.MqSimpleFeign;
import com.ocom.payhandle.feign.UgcapiFeign;
import com.ocom.payhandle.feign.XfRecordFeign;
import com.ocom.payhandle.mq.config.SyncSaveOrderConfig;
import com.ocom.payhandle.service.*;
import com.ocom.payhandle.vo.MqSaveOrderVo;
import com.ocom.redis.util.RedisUtil;
import com.rabbitmq.client.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;


@Component
public class SaveOrderMqListener {

	private Logger logger = LoggerFactory.getLogger(SaveOrderMqListener.class);


	@Autowired
	private XfRecordProcessService xfRecordProcessService;

	@Autowired
	private XfGoodsListProcessService xfGoodsListProcessService;

	@Autowired
	private XfRecordFeign xfRecordFeign;

	@Autowired
	private XfMerchPayInfoService xfMerchPayInfoService;


	@Autowired
	private UgcapiFeign ugcapiFeign;

	@Autowired
	AbnormalService abnormalService;

	@Autowired
	private XfAccountTypeService xfAccountTypeService;

	@Autowired
	private CompanyConfigService companyConfigService;

	@Resource
	private RedisUtil redisUtil;


	@Autowired
	private MqSimpleFeign mqSimpleFeign;

	@Autowired
	XfRecordProcessExxxService xfRecordProcessExxxService;

	/**
	 * 把该监听命名为A监听
	 * 监听队列  远程服务支付接口发送消息  该队列会接受
	 * [message, headers, channel]
	 * @return {@link }
	 * @throws
	 */
	@RabbitListener(queues = SyncSaveOrderConfig.SYNC_SAVE_ORDER_QUEUE)
	public void process(Message message, @Headers Map<String, Object> headers, Channel channel) throws Exception {
//		logger.info("SavrOrderMqListener_queue 消费中");
//		logger.info("message【{}】",message);
//		try {
//			Thread.sleep(500);//延迟半秒执行
//		}catch(InterruptedException e){
//			logger.info("mq消息队列迁移订单 异常 gjfOAWx3Pb 【{}】【{}】",message,e);
//		}

		String msg = new String(message.getBody(), StandardCharsets.UTF_8);
		MqSaveOrderVo mqSaveOrderVo = JSON.parseObject(msg, MqSaveOrderVo.class);
//		logger.info("消费数据 【{}】 【mq优先级】 【{}】 ",mqSaveOrderVo,message.getMessageProperties().getPriority());

		if(mqSaveOrderVo.getId() == null ){
			logger.info("SavrOrderMqListener_queue id 空 手动签收消息,通知mq服务器端删除该消息");
			//私信队列记录
			channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
			return;
		}

		Long inceTime = redisUtil.incr("syncSaveOrder#comId:"+mqSaveOrderVo.getComId()+"#:incr:"+mqSaveOrderVo.getId(), 1l);

		redisUtil.expire("syncSaveOrder#comId:"+mqSaveOrderVo.getComId()+"#:incr:"+mqSaveOrderVo.getId(),3600l);
	    //TODO 数据库操作样例
		logger.info("SavrOrderMqListener-start:【{}】【{}】【{}】",mqSaveOrderVo.getComId(),mqSaveOrderVo.getId(),msg);
//		logger.info("System.currentTimeMillis()【{}】",System.currentTimeMillis());

		try {

			EntityXfRecordProcessExxx entityXfRecordProcess = xfRecordProcessExxxService.selectTradeNo(mqSaveOrderVo.getComId(),mqSaveOrderVo.getId());

			EntityXfRecord entityXfRecord = JSONObject.parseObject(JSON.toJSONString(entityXfRecordProcess),EntityXfRecord.class);
			Result result= null;
			if(mqSaveOrderVo.getType()<3){
//				logger.info("异步迁移订单: entityXfRecord【{}】",entityXfRecord);
				if(mqSaveOrderVo.getType()!=2){   //2 仅迁移
					entityXfRecord.setPayState(1);
				}
//				entityXfRecord.setCreateTime(null);
				result = xfRecordFeign.sveXfRecord(entityXfRecord);
			}else if (mqSaveOrderVo.getType() == 3){ //更新
				entityXfRecord.setConsState(5);
				result = xfRecordFeign.updateXfRecord(entityXfRecord);
			}

//			//查订单
			if(entityXfRecord.getConsType()==100 || entityXfRecord.getConsState()==3 || entityXfRecord.getConsState()==5 || entityXfRecord.getConsState()==205){
				try {
					List<EntityXfGoodsListProcess> listProcesses =  xfGoodsListProcessService.getXfGoodsList(entityXfRecord.getComId(),entityXfRecord.getOrderNo());
					if(listProcesses!=null && listProcesses.size()>0){
						List<EntityXfGoodListOrg> listOrgs =JSON.parseArray(JSON.toJSONString(listProcesses),EntityXfGoodListOrg.class);
						if(mqSaveOrderVo.getType()<3) {
							xfRecordFeign.saveXfGoodListBatch(listOrgs);
						}else if (mqSaveOrderVo.getType() == 3 && entityXfRecord.getIfRefund()==1){
							RefundOrderDishesRequest refundOrderDishesRequest =new RefundOrderDishesRequest();
							refundOrderDishesRequest.setComId(entityXfRecordProcess.getComId());
							refundOrderDishesRequest.setOrderNo(entityXfRecord.getOrderNo());
							refundOrderDishesRequest.setMonthValue(entityXfRecordProcess.getMonthValue());
							refundOrderDishesRequest.setRemark("菜品退款");
							xfRecordFeign.refund(refundOrderDishesRequest);
						}
					}
				} catch (Exception e) {
					logger.error("mq迁移菜品报错  【{}】 【{}】【{}】",entityXfRecord.getOrderNo(),entityXfRecord,e);
				}
			}

			EntityCompanyConfig hongBao = companyConfigService.getTapValue(entityXfRecordProcess.getComId(), "hongBao");

			if(entityXfRecord.getPayWay()==7
			&& (entityXfRecord.getOpTypeDiff() == 201l || entityXfRecord.getOpTypeDiff() == 202l
					|| (hongBao!=null &&  hongBao.getConfig().equals("true")) )){
				String canKey  = "delayqueryFee#comId:" +entityXfRecord.getComId()+"#orderNo:"+entityXfRecord.getOrderNo();
				Object ex = redisUtil.get(canKey);
				if(ex==null){
					//调用延迟mq
					EntiyXfMerchPayInfo entiyXfMerchPayInfo = xfMerchPayInfoService.selectConfigure(entityXfRecord.getComId(),entityXfRecord.getPayChannelNo());
					if(entiyXfMerchPayInfo!=null){
						try {
							ServiceChargesVo serviceChargesVo =new ServiceChargesVo();
							serviceChargesVo.setCompanyId(entiyXfMerchPayInfo.getCompanyId());
							serviceChargesVo.setUserName(entiyXfMerchPayInfo.getUserName());
							serviceChargesVo.setPassword(entiyXfMerchPayInfo.getPassword());
							serviceChargesVo.setMachNo("00000000");
							serviceChargesVo.setComId(entityXfRecord.getComId());
							serviceChargesVo.setTradeNo(entityXfRecord.getOrderNo());
							ugcapiFeign.serviceCharges(serviceChargesVo);
							redisUtil.set(canKey,canKey,180l);
						}catch (Exception e){
							logger.info("查询费率异常 ,【{}】",mqSaveOrderVo);
						}

					}
				}
			}


			try {
				EntityCompanyConfig entityCompanyConfig = companyConfigService.getTapValue(entityXfRecordProcess.getComId(), "gzhMsg");
				if (entityXfRecord.getPayState()==1 && entityCompanyConfig != null && entityCompanyConfig.getConfig().equals("true") && entityXfRecordProcess.getAccTypeId()>0) {
					GzhMsgRequest gzhMsgRequest = new GzhMsgRequest();
					gzhMsgRequest.setComId(entityXfRecordProcess.getComId());
					gzhMsgRequest.setMerchId(entityXfRecordProcess.getMerchId());
					gzhMsgRequest.setPId(entityXfRecordProcess.getPId());
					gzhMsgRequest.setOrderNo(entityXfRecordProcess.getOrderNo());
					gzhMsgRequest.setType(2);
					gzhMsgRequest.getParams().setUserName(entityXfRecordProcess.getPName());
					gzhMsgRequest.getParams().setPayTime(DateUtil.getDateTime(entityXfRecordProcess.getConsTime()));
					gzhMsgRequest.getParams().setPayMoney(AcpService.stringAmount(entityXfRecordProcess.getConsMoney().toString()));
					gzhMsgRequest.getParams().setBalance(AcpService.stringAmount(entityXfRecordProcess.getChargeBalance().toString()));
					gzhMsgRequest.getParams().setPointName("饭堂");
					if(!CommonUtil.isNull(entityXfRecordProcess.getPointName())){
						gzhMsgRequest.getParams().setPointName(entityXfRecordProcess.getPointName());
					}

					gzhMsgRequest.getParams().setAccTypeName("");
					EntityXfAccountType entityXfAccountType = xfAccountTypeService.getXFAccountType(entityXfRecordProcess.getComId(), entityXfRecordProcess.getAccTypeId());
					if (entityXfAccountType != null) {
						gzhMsgRequest.getParams().setAccTypeName(entityXfAccountType.getAccTypeName());
					}
					mqSimpleFeign.gzhMsg(gzhMsgRequest);
				}
			} catch (Exception exception) {
				logger.info("公众号消息发送失败:{{}}", exception.getMessage());
			}

//			logger.info("异步迁移订单: result【{}】",result);
			if (result == null || (result.getCode()!=200 &&  result.getCode()!=802)){
				logger.error("mq迁移成功库失败 wa64zvlq  【{}】 【{}】【{}】",entityXfRecord.getOrderNo(),entityXfRecord,result);
			}else{
				if(mqSaveOrderVo.getType()==1){
					abnormalService.delAbnormal(mqSaveOrderVo.getComId(),mqSaveOrderVo.getId().toString());
				}
				// 手动签收消息,通知mq服务器端删除该消息
				channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
				return;
			}
		} catch (Exception e) {
			logger.info("mq消息处理失败:【{}】【{}】",msg,e);
		}


		//重试3次
		if(inceTime>=3l){
			logger.info("出现异常后，原本队列消息进入死信队列");
			logger.info("SavrOrderMqListener-end-重试次数:【{}】",inceTime);
			//出现异常后，原本队列消息进入死信队列
			channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
		}else{
			logger.info("不满3次 继续消费");
			channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);//继续消费该消息
		}

	}

	/**
	 * 把该监听命名为B监听
	 * 监听死信队列  远程服务支付接口发送消息  该队列会接受
	 * [message, headers, channel]
	 * @return {@link }
	 * @throws
	 */
	@RabbitListener(queues =   SyncSaveOrderConfig.SYNC_SAVE_ORDER_DIE_QUEUE)
	public void processForDie(Message message, @Headers Map<String, Object> headers, Channel channel) throws Exception {

		try {
			String msg = new String(message.getBody(), StandardCharsets.UTF_8);
			MqSaveOrderVo mqSaveOrderVo = JSON.parseObject(msg, MqSaveOrderVo.class);
			if(mqSaveOrderVo.getType()==1){
				//死信队列放弃
				channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
				return;
			}
			EntityAbnormal entityAbnormal=new EntityAbnormal();
			entityAbnormal.setComId(mqSaveOrderVo.getComId());
			entityAbnormal.setPlatOrderNo(mqSaveOrderVo.getId().toString());
			entityAbnormal.setType(2);
			entityAbnormal.setRemark("mq迁移失败");
			abnormalService.Add(mqSaveOrderVo.getComId(),entityAbnormal);
		}catch (Exception e){
			logger.error("异步迁移成功订单失败  死信队列记录  - 异常, 【{}】",e);
		}


		//死信队列放弃
		channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
		//插入异常  TODO
		logger.info("异步迁移成功订单失败  死信队列记录 , 【{}】",message);
	}

}
